#include<stdio.h>
#include<at89c51ed2.h>
#include<mcs51reg.h>
#include<malloc.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#include "io.h"
#include "eeprom.h"
#include "glcd.h"
#include "cywm6935.h"
#include "spi.h"
#include "rtc.h"
#include "graphics.h"
#include "sst25vf080b.h"
#include "sst25vf080_read.h"
#include "sst25vf080_write.h"
#include "logger.h"




/*****************************************************************************/
/**Critical Initialisation. Serial Communication at 19200 baud, XRAM 
 * 1024 bytes activated. This function has reference on Page 41 of 
 * the SDCC Manual*/
void _sdcc_external_startup() {
	AUXR|=0x0C;	/*XRAM 1024 bytes activated*/
	TMOD=0x21;	/*Timer 1 Mode 2*/
	TH1=0xFD;	/*Timer Value 253 for baud rate 9600*/
	SCON = 0x50;/*SCON: mode 1, 8-bit UART, enable receiver*/
	PCON|=0x80;	/*double baud rate to 19200*/
	TR1 = 1; 	/*Start Timer 1 */
	RI = 0;		/*clear RI flag for getchar sequence*/
	TI=1;
}
/*****************************************************************************/


/********************************static******************/
xdata static unsigned char rssiVal[78]; /*store 78 MHz data */ /**was int before**/
static unsigned char timeUpdater;
static bit time_date; //0 for time 1 for date
static unsigned char subgraph_channel;
static bit logMode;  //0 for real time 1 for scan mode
static bit startLogging; //0 for off, 1 for on
static unsigned char checkNoscans;
static unsigned char nextScan;
volatile static char displayMode;


#define maxY 			56
#define freqNormaliser 2
#define firstFreq      2  /*represents 2.402 */
#define datePrint	   92
#define frameLength	   86



/*****************************************************************************/	
/**Defined the Timer 0 overflow ISR. This ISR will be called every 1000 */
//
void timer0_overflow(void) __interrupt (1) using (3)
//void timeUpdate()
{
	
	timeUpdater++;
	
	if(timeUpdater==250)
	{
		
		timeUpdater=0; //make it back to zero after 5 sec

		
		if(time_date==0)
		{
		/**********************print time*****************/
		clrString(7,datePrint,8);
		printTime(datePrint+6,1);	
		time_date=1;
		}
		else{
			/**********************print date*****************/
		clrString(7,datePrint,8);
		printTime(datePrint,2);	
		time_date=0;
		
		}
	}
	

}
///*****************************************************************************/

int checkChannelAct(int center_freq)
{
	int upperavg;
	int loweravg;
	int i;
	int decision;
	int lowerSlope;
	int upperSlope;
	
	loweravg=0;
	upperavg=0;
	lowerSlope=0;
	upperSlope=0;
	


	for(i=0;i<5;i++) //read the lower 5 frequencies
	{
	//printf("Lower %d\n\r",rssiVal[center_freq-freqNormaliser-5+i]);
	
//	while(i>0)
//	{
//	if((rssiVal[center_freq-freqNormaliser-5+i]>rssiVal[center_freq-freqNormaliser-6+i]))
//	{
//		lowerSlope++;
//		
//	}
//	}
	
	loweravg=loweravg+rssiVal[center_freq-freqNormaliser-5+i];
	
	
	}
	
	for(i=5;i<10;i++) //read the upper 5 frequencies
	{
	//printf("Upper %d\n\r",rssiVal[center_freq-freqNormaliser+i-4]);
	
//	while(i>5)
//	{
//	if((rssiVal[center_freq-freqNormaliser+i-4]>rssiVal[center_freq-freqNormaliser+i-3]))
//	{
//		upperSlope++;
//		
//	}
//	}
	

	upperavg=upperavg+rssiVal[center_freq-freqNormaliser+i-4];	
	}


	upperavg=(upperavg/5);
	loweravg=(loweravg/5);
	printf("Upper Avg : %d Lower Avg : %d  Channel Number: %d\n\r",upperavg,loweravg,center_freq);

	if((getAbsValue(upperavg,loweravg)<5)&&upperavg>14&&loweravg>14)
	{
		decision=1;
	}
	else
	{
		decision=0;
	}
	//printf("upperSLope %d",upperSlope);
//printf("lowerSLope %d",lowerSlope);


	return decision;	
}





void drawChannel(int centerFreq)
{
	int i;
	int j;
	char chNum[3];
	volatile char modeSelector;
	_itoa(channelNumber(centerFreq),chNum,10);
	/*small graph*/
	
	drawHorzLine(31,100,27); /*horizontal line*/
	drawVertLine(100,0,31);	/*vertical line*/
	
	/*print which channel has been displayed*/
	

	_itoa(channelNumber(centerFreq),chNum,10);
	clrString(4,105,5);
	drawString("CH:",4,105);
	drawString(chNum,4,116);
	
	/***select the displat mode********/
	 modeSelector=displayMode;
	if(modeSelector==1)
	{
	/*display lower 10 frequecies*/
	for(i=0;i<11;i++)
	{
	//printf("Value : %d\n\r",rssiVal[centerFreq-freqNormaliser-11+i]); //should print from 2.402-2.412
	clrVertLine(101+i,0,31);	
	drawVertLine(100+i,31-(rssiVal[centerFreq-freqNormaliser-11+i]),(rssiVal[centerFreq-freqNormaliser-11+i]));
	}
	
	/*display center freq*/
	//printf("Center Freq: %d\n\r", rssiVal[centerFreq-freqNormaliser]);
//	clrVertLine(101+i,10,31);	
//	drawVertLine(100+i,41-(rssiVal[centerFreq-freqNormaliser]),(rssiVal[centerFreq-freqNormaliser]));
//	i++; /*increment i to continue x mapping*/
	
	
	/*display higher frequencies*/
	for(j=0;j<12;j++)
	{
		clrVertLine(101+j+i,0,31);
		drawVertLine(100+j+i,31-(rssiVal[centerFreq-freqNormaliser+j]),(rssiVal[centerFreq-freqNormaliser+j]));
		
		//printf("Value : %d\n\r",rssiVal[centerFreq-freqNormaliser+j+1]); //should print from 2.402-2.412
	}
	
	}
	
	if(modeSelector==2)
	{
		
		/*display lower 10 frequecies*/
	for(i=0;i<11;i++)
	{
	clrVertLine(101+i,0,31);
	drawBLine(100+i,(31-rssiVal[centerFreq-freqNormaliser-11+i]),101+i, (31-rssiVal[centerFreq-freqNormaliser-11+i+1]));
	}
	
	
	/*display higher frequencies*/
	for(j=0;j<12;j++)
	{
		clrVertLine(101+j+i,0,31);
		drawBLine(100+j+i,(31-rssiVal[centerFreq-freqNormaliser+j]),101+i+j, (31-rssiVal[centerFreq-freqNormaliser+j+1]));
	}
		
		
	}
	
	
	
}

/********************************************************************/
//
void ioExpander(void) __interrupt (2)/*__using(2)*/ /*low priority that timer 0*/
{
	
	/*toggle p7, reset p5 as input ie make it high*/
	unsigned char IOreader;
	unsigned char i;
	unsigned char dBounce;
	
	dBounce=1;
	
	
	for(i=0;i<10;i++){
		delay(50);
		IOreader=i2cexpanderRead();
		
		dBounce=deBouncer(IOreader);
			
	}
	
	
	if(dBounce==1&&((IOreader&0x20)==0)){
	
/****draw channel part*********/
	drawChannel(subgraph_channel);
	subgraph_channel=subgraph_channel+5;
	
	if(subgraph_channel>62)
	{
	subgraph_channel=12;
	}
	
	}

///********change scan mode/ real time mode***********/

if(dBounce==1&&((IOreader&0x02)==0)){
	if(logMode==0){
		logMode=1;
		TR0=0;
	}
	else
	{
		logMode=0;
		TR0=1;
	}
}

/////***********change bar/line mode*********/
if(dBounce==1&&((IOreader&0x01)==0)){
	if(displayMode==1){
		displayMode=2;
	}
	else
	{
		displayMode=1;
	}
}

//
/////***********in scan mode, to move between scans*********/
//if(dBounce==1&&((IOreader&0x01)==0)){
//	
//	nextScan=1;   //user has entered the option to go to next scan
//	
//}



///***********in real mode, to initiate logging, in scan mode to move between scans********/
if(dBounce==1&&((IOreader&0x04)==0)){
	
	
if(logMode==0) //real-time mode
{	

	if(startLogging==0)
	{
	startLogging=1;   //user has entered the option to start logging in real-mode
	}
	else 
	{
		startLogging=0;
	}
}
if(logMode==1)
{	
	nextScan=1;   //user has entered the option to go to next scan
}



}
}
	


/***********************************************************************************/

/*********************rssi scan*********************/ /*working*/
	void scanRSSI(int magnifier) //1 for bar 2 for dotted
	{
	int x_graphStart;
	int i;
	unsigned char displayModeCheck;
	x_graphStart=9;

	displayModeCheck=displayMode;
	
		if(displayModeCheck==2)
	{
		clrString(5,datePrint,8); //tell the user that data is getting loaded
		drawString("LOADING",5,datePrint);
	}
	
	
	for(i=0;i<72;i++)
	{
		
	rssiVal[i]=rssiRead(i+2);
	printf("Frequency 2.4%d \t RSSI %d \n\r",spi_dataRead(0x21,1),rssiVal[i]);
	
	
	if(displayModeCheck==1)
	{
	clrVertLine(x_graphStart+i,25,maxY-25);		
	drawVertLine(x_graphStart+i,(maxY-(rssiVal[i])),(magnifier)*(rssiVal[i]));
	}
	

	}
	
	if(displayModeCheck==2)
	{
		clrString(5,datePrint,8); //tell the user that data is getting loaded
		clrVertLine(x_graphStart,25,maxY-25);		
		
		for(i=0;i<72;i++)
	{
		clrVertLine(x_graphStart+1,25,maxY-25);	
		drawBLine(x_graphStart, (magnifier)*(maxY-rssiVal[i]),x_graphStart+1, (magnifier)*(maxY-rssiVal[i+1]));
		x_graphStart=x_graphStart+1;
	}
	}
	
	
//	
	}
	
	
	
	void displayScan(int magnifier,int scanNumber)//1 for bar 2 for dotted
	{
	long int scanAddress;
	unsigned char page;
	unsigned char col;
	unsigned char hour;
	unsigned char min;
	unsigned char date;
	unsigned char val[5];
	volatile char modeSelector;
	unsigned char centerFreq;
	unsigned int activeFreqs[6];
	unsigned char channelPrinter;
	unsigned char chNum[3];
	

	
			
	int x_graphStart;
	int i;
	
	/***time position***/
	page=7;
	col=datePrint+8;


	x_graphStart=9;

	/*scan number start from 1, so '-1'*/

	scanAddress=(scanNumber-1)*frameLength; //get starting address of scan
	
	/*will print time first*/
	
	

	/*read hour and min*/
	hour=readFromLoc(scanAddress+4);
	min=readFromLoc(scanAddress+5);
	date=readFromLoc(scanAddress+3);


/********print scan number***/
clrString(page-2,datePrint,8);
drawString("SCAN:",page-2,datePrint);
_itoa(scanNumber,val,10);
drawString(val,page-2,datePrint+20);
	
/**clear previous scan time and date**/
clrString(page-1,datePrint,9);
clrString(page,datePrint,8);

if(hour<10)
{
	 drawString("0",page,col);
	_itoa(hour,val,10);
	 drawString(val,page,col+4);
	 drawString(":",page,col+8);
	 
		if(min<10){
		drawString("0",page,col+12);
		_itoa(min,val,10);
		drawString(val,page,col+16);
		}
		else
		{
		_itoa(min,val,10);
		drawString(val,page,col+12);
		}
}
else
{
	_itoa(hour,val,10);
	 drawString(val,page,col);
	 drawString(":",page,col+8);
	
		if(min<10){
		drawString("0",page,col+12);
		_itoa(min,val,10);
		drawString(val,page,col+16);
		}
		else
		{
		_itoa(min,val,10);
		drawString(val,page,col+12);
		}
}
/***********************************************************************************/
/***print date**********/

	drawString("12",6,datePrint);  //see this problem later, month is printed twice
		
		
			if((date)<10)
			{
			drawString("|0",6,datePrint+8);
			_itoa(date,val,10);
			drawString(val,6,datePrint+16);
			}
			else
			{
			drawString("|",6,datePrint+8);
			_itoa(date,val,10);
			drawString(val,6,datePrint+12);
			}
		
		drawString("|",6,datePrint+20);
		drawString("12",6,datePrint+24);  //see this problem later, month is printed twice
		//drawString(year,0,datePrint+23);
	
		
	
/********************************************************************************************/

	modeSelector=displayMode;

	for(i=0;i<72;i++) /**get all stored data**/
	{
		rssiVal[i]=readFromLoc(scanAddress+7+i);
	}
	
/***********************************************************************************/
for(i=0;i<72;i++)
	{
	
	if(modeSelector==1)
	{
	clrVertLine(x_graphStart+i,25,maxY-25);	
	drawVertLine(x_graphStart+i,(maxY-(rssiVal[i]*magnifier)),(magnifier)*(rssiVal[i]));
	}
	}
	
	if(modeSelector==2)
	{
		
		clrVertLine(x_graphStart,25,maxY-25);		
		
		for(i=0;i<72;i++)
	{
		clrVertLine(x_graphStart+1,25,maxY-25);	
		//clrVertLine(x_graphStart+2,25,maxY-25);		
		//printf("Val %d\n\r",x_graphStart+i+2);
		drawBLine(x_graphStart, (magnifier)*(maxY-rssiVal[i]),x_graphStart+1, (magnifier)*(maxY-rssiVal[i+1]));
		x_graphStart=x_graphStart+1;
	}
	}
	
	
	
	
	///*************check channel*******************/
clrString(1,60,10);
for(i=0;i<6;i++)
{
activeFreqs[i]=0;
}
i=0;
channelPrinter=60;

centerFreq=12;

//clrString(0,channelPrinter+12,channelPrinter+25); //interesting!!!
while(centerFreq<67)
{

if(checkChannelAct(centerFreq)==1)
{
	_itoa(channelNumber(centerFreq),chNum,10);
	activeFreqs[i]=centerFreq;//put active freqs in array for data logging
	i++;
	 drawString(chNum,1,channelPrinter);	
	 drawString(" ",0,channelPrinter+4);	
	 channelPrinter=channelPrinter+6;
}
	centerFreq=centerFreq+5;
}
	
	
	
	

	
	
	
	}
		
	
	
	
	



	

void main(){

unsigned char i;
unsigned char centerFreq;
unsigned char channelPrinter;
unsigned char chNum[3];
bit	logModeSampler;
bit startLoggingSampler;
unsigned char logOffSet;
unsigned int startAddress;
unsigned int activeFreqs[6];
unsigned int scanNumber;






//	
//
///************************init***********************/
//
///*glcd*/
glcd_init();
glcd_clr(0x00);
//
////
/////*rssi chip init*/
Master_spi_init(1); //for rssi chip*/
chipInit();

/////***************************************************/
/////***********************graph markers**************/
drawGraph(1);
drawGraphMarkers(1); //x1 mode
/*******************log mode setting*********************/
logMode=0; //defualt to real-time scanning***/
nextScan=0;
checkNoscans=0;

/////**************************************************/

/////****setup interrupts************/
	//TMOD|=0x01; /*timer 0, 16-bit Timer Mode*/
	EA=1; 		/*set Global Interrupts*/
	ET0=1; 		/*set Timer 0 Overflow Interrupt*/
	
	EX1=1;  /*Enable Low level triggered external interrupt 1*/
	subgraph_channel=12;
	displayMode=1;
	TH0=0x00;/*Load Counter value for Normal Mode (1 ms)*/
	TL0=0x00; 		
	 
	time_date=1;  //set default display to date

/////**********************print time*****************/


/*******************logging option*************/
startLogging=0; //no logging by default
/************************************************/

/******************menu and device status**********/
drawString("MODE:",0,0);




drawString("CH IN USE",0,60);

drawVertLine(57,0,20);
drawHorzLine(20,0,101);
drawVertLine(100,0,20);

while(1)
{

logModeSampler=logMode;

if(logModeSampler==0) //real-time mode
{
	
clrString(7,datePrint,8);
printTime(datePrint+8,1);
clrString(6,datePrint,8);
drawString("TIME|DATE",6,datePrint);	


timeUpdater=0;
time_date=1; //print date for the first ISR execution
TR0=1; /*start timer*****/	
	
	
clrString(0,20,5);
drawString("REAL-TIME",0,20);

clrString(1,0,12);
drawString("LOGGING:",1,0);





startLoggingSampler=startLogging;
if(startLoggingSampler==1)
{

clrString(1,31,3);
drawString("ON",1,31);
}
else
{

clrString(1,31,3);
drawString("OFF",1,31);	

}

scanRSSI(1);



////timeUpdate();
//
///*************check channel*******************/
clrString(1,60,10);
for(i=0;i<6;i++)
{
activeFreqs[i]=0;
}
i=0;
channelPrinter=60;

centerFreq=12;

//clrString(0,channelPrinter+12,channelPrinter+25); //interesting!!!
while(centerFreq<67)
{

if(checkChannelAct(centerFreq)==1)
{
	_itoa(channelNumber(centerFreq),chNum,10);
	activeFreqs[i]=centerFreq;//put active freqs in array for data logging
	i++;
	 drawString(chNum,1,channelPrinter);	
	 drawString(" ",0,channelPrinter+4);	
	 channelPrinter=channelPrinter+6;
}
	centerFreq=centerFreq+5;
}

/*********************data logging ops************/

if(startLoggingSampler==1)
{

checkNoscans=0; //prevent scan mode to lose on scans when device was on
logOffSet=0;
startAddress=determineStartPosn();

	
	writeFromAnyLocation(startAddress+logOffSet,0xAA); //write data identifier
	logOffSet++;
	writeFromAnyLocation(startAddress+logOffSet,readYear()); //write year
	logOffSet++;
	writeFromAnyLocation(startAddress+logOffSet,readMonth()); //write year
	logOffSet++;
	writeFromAnyLocation(startAddress+logOffSet,readDate()); //write year
	logOffSet++;
	writeFromAnyLocation(startAddress+logOffSet,readHour()); //write hour
	logOffSet++;
	writeFromAnyLocation(startAddress+logOffSet,readMin()); //write Min
	logOffSet++;
	writeFromAnyLocation(startAddress+logOffSet,0xAB); //raw data identifier
	logOffSet++;
	
	for(i=0;i<72;i++)
	{
		writeFromAnyLocation(startAddress+logOffSet,rssiVal[i]); //raw data identifier
		logOffSet++;
		
	}
	
	writeFromAnyLocation(startAddress+logOffSet,0xAC); //channel ident data identifier
	logOffSet++;
	
	for(i=0;i<6;i++)
	{
		writeFromAnyLocation(startAddress+logOffSet,activeFreqs[i]); //channel data identifier
		logOffSet++;
		
	}
}



}


if(logModeSampler==1)
{
clrString(0,20,9);
drawString("SCAN",0,20);	



clrString(0,60,10);
clrString(1,60,10);
drawString("CH IN USE",0,60);


if(checkNoscans==0) //checked only once 
	{
		startAddress=determineStartPosn();
		if(startAddress==0) //if no scans in memory
		{	
			clrString(6,datePrint,9);
			drawString("NO SCANS",6,datePrint);
			for(i=0;i<255;i++)
			{
			delay(50000);
			delay(50000);
			delay(50000);
			delay(50000);
			delay(50000);
			delay(50000);
			
			}
			
			logMode=0; //shift back to real-time mode
		}
		else
		{
			checkNoscans=1;
		}
		
	}




clrString(1,0,12); //clear loggnng and write number of scans
drawString("SCANS AVBL:",1,0);

/**print number of scans**/
clrString(1,45,3);
_itoa((startAddress/frameLength),activeFreqs,10);
drawString(activeFreqs,1,45);

if(checkNoscans==1)
{

	displayScan(1,1); /**displat first scan in memory***/
	scanNumber=1;


logOffSet=0;
back:	while((nextScan==0)&&logMode==1) //wait till user selects next scan or exits scan mode
		{
	
		}
		
		
		//printf("so called start address %d,,scan number %d\n\r",startAddress,scanNumber);
		if(nextScan==1)
		{
			//printf("log mode %d\n\r",logMode);
			nextScan=0;  //make it back to zero
			if((startAddress)==(scanNumber*frameLength))  //prevent exceeding more than number of stored scans
			{
				scanNumber=0;
			}
			scanNumber++;
			displayScan(1,scanNumber);
			
			
			
			
			
			
			goto back;
		}
		
	}

   }


	
	
	


}

}

